home *** CD-ROM | disk | FTP | other *** search
- /*
- sdwarn.c --- example shutdown client.
-
- (c) Copyright 1995-98 SHW Wabnitz
- Written by Bernhard Fastenrath (fasten@shw.com)
-
- This file may be distributed under the terms
- of the GNU General Public License.
- */
-
- /// Includes & Declarations
- #if defined (__SASC)
- #include <dos.h>
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <exec/types.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include "queue/queue.h"
- #include "queue/shutdown.h"
-
- #if defined (__GNUC__)
- #include "queue/queue_inline.h"
- #elif defined (__SASC_60)
- #include "queue/queue_pragmas.h"
- #endif
-
- void CloseTimerDevice (void);
- int CheckCLISession (void);
-
- struct Library *QueueBase = NULL;
- struct timerequest *TimerReq = NULL;
- struct MsgPort *TimerPort = NULL;
- ULONG TimerMask = 0;
- ULONG QueueMask = 0;
- ULONG CliNumber = 0;
- BPTR CliStdout = NULL;
- struct Process *MyProc;
- APTR WindowPtr;
-
- char *optarg = NULL;
- ///
-
- /// getopt()
- int
- getopt (int argc, char *const *argv, const char *opts)
- {
- static int pos = 0;
- char *c;
-
- while (++pos < argc && argv[pos][0] != '-');
- if (pos >= argc)
- return -1;
- if ((c = strchr (opts, (int) argv[pos][1])) == 0)
- return (int) '?';
- if (*(c+1) != ':')
- return (int) *c;
- if (strlen (argv[pos]) > 2)
- optarg = argv[pos] + 2;
- else if (pos+1 < argc)
- optarg = argv[pos+1];
- else
- return (int) '?';
- return (int) *c;
- }
- ///
-
- /// CheckCLISession()
- int
- CheckCLISession (void)
- {
- struct Process *pr;
- int code = 0;
-
- if (!CliNumber)
- return 1;
-
- Forbid ();
- if (pr = FindCliProc (CliNumber))
- {
- /* We might have found a new CLI
- with the same number.
- */
- if (pr -> pr_COS == CliStdout)
- code = 1;
- }
- Permit ();
- return code;
- }
- ///
-
- /// CloseTimerDevice()
- void
- CloseTimerDevice (void)
- {
- if (!TimerPort)
- return;
-
- AbortIO ((struct IORequest *) TimerReq);
- WaitIO ((struct IORequest *) TimerReq);
- CloseDevice ((struct IORequest *) TimerReq);
- DeleteIORequest (TimerReq);
- DeleteMsgPort (TimerPort);
- TimerPort = NULL;
- }
- ///
-
- /// StartTimer()
- void
- StartTimer (void)
- {
- if (TimerPort)
- {
- TimerReq -> tr_node.io_Command = TR_ADDREQUEST;
- TimerReq -> tr_time.tv_secs = 3;
- TimerReq -> tr_time.tv_micro = 0;
- SendIO ((struct IORequest *) TimerReq);
- }
- }
- ///
-
- /// OpenTimerDevice()
- ULONG
- OpenTimerDevice (void)
- {
- if (!(TimerPort = CreateMsgPort ()))
- return 0;
-
- if (!(TimerReq = (struct timerequest *)
- CreateIORequest (TimerPort, sizeof (struct timerequest))))
- {
- DeleteMsgPort (TimerPort);
- return 0;
- }
- if (OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerReq, 0))
- {
- DeleteIORequest (TimerReq);
- DeleteMsgPort (TimerPort);
- return 0;
- }
- StartTimer ();
- return TimerMask = 1 << TimerPort -> mp_SigBit;
- }
- ///
-
- /// GoingDownMessage()
- void
- GoingDownMessage (int seconds)
- {
- if (seconds / 3600)
- printf ("The system is going down in %d:%.2d hours.\n",
- seconds / 3600, (seconds % 3600) / 60);
- else if (seconds / 60)
- printf ("The system is going down in %d:%.2d minutes.\n",
- seconds / 60, seconds % 60);
- else
- printf ("The system is going down in %d seconds.\n", seconds);
- }
- ///
-
- /// main()
- int
- main (int argc, char *argv[])
- {
- QMessage *qmsg, *lqmsg;
- ShutdownMessage *sm;
- UpsInfo *ups;
- char *UpsEvents[] = UPS_EV_NAMES;
- int verbose = 0;
- ULONG sigbit, sigmask, rmask;
- QHandle qh;
- int opt;
-
- MyProc = (struct Process *) FindTask (0);
- WindowPtr = MyProc -> pr_WindowPtr;
- MyProc -> pr_WindowPtr = (void *) -1;
-
- while ((opt = getopt (argc, argv, "c:v")) != -1)
- switch (opt)
- {
- case 'v': verbose = 1; break;
- case 'c':
- if (CliNumber = atoi (optarg))
- {
- struct Process *pr;
-
- Forbid ();
- if (pr = FindCliProc (CliNumber))
- CliStdout = pr -> pr_COS;
- Permit ();
- if (!CliStdout)
- {
- printf ("Invalid CLI.\n", CliNumber);
- exit ( EXIT_FAILURE );
- }
- }
- break;
- default:
- printf ("Usage: %s [-v] [-c <cli>].\n", argv[0]);
- exit (EXIT_FAILURE);
- }
-
- if (!(QueueBase = OpenLibrary ("queue.library", 0)))
- {
- printf ("Failed to open queue.library.\n");
- return EXIT_FAILURE;
- }
- if (CliNumber)
- {
- if (!OpenTimerDevice ())
- {
- printf ("Failed to open timer.device.\n");
- CloseLibrary (QueueBase);
- return EXIT_FAILURE;
- }
- }
- if ((sigbit = AllocSignal (-1)) != -1)
- {
- QueueMask = 1 << sigbit;
- sigmask = SIGBREAKF_CTRL_C | TimerMask | QueueMask;
-
- if (qh = QOpen ("shutdown", QMODE_LISTEN, sigbit))
- {
- while (1)
- {
- rmask = Wait (sigmask);
- if (rmask & TimerMask)
- StartTimer ();
-
- if (rmask & QueueMask)
- {
- lqmsg = NULL;
- while (qmsg = QGetMsg (qh))
- {
- sm = (ShutdownMessage *) qmsg -> qm_Data;
- lqmsg = qmsg;
-
- switch (sm -> sm_Status)
- {
- case SHUTDOWN_WARN:
- case SHUTDOWN_NOW:
- GoingDownMessage (sm -> sm_TimeLeft);
- break;
- case SHUTDOWN_INFO:
- if (verbose)
- {
- if (sm -> sm_Info == SDMI_UPS_MONITOR)
- {
- printf ("Shutdown info received:\n");
- ups = sm -> sm_Extra;
- if (ups -> ui_Event > UPS_EV_MAX)
- printf ("Event = %d (unknown)\n", ups -> ui_Event);
- else
- printf ("Event = %s.\n", UpsEvents[ups -> ui_Event]);
- printf ("Charge = %d.\n", ups -> ui_Charge);
- printf ("Remaining time = %d.\n", ups -> ui_Time);
- }
- else
- printf ("Shutdown info received.\n");
- }
- break;
- case SHUTDOWN_ABORT:
- printf ("Shutdown has been aborted.\n");
- break;
- case SHUTDOWN_UMOUNT:
- printf ("The system is going down, unmounting filesystems.\n");
- break;
- case SHUTDOWN_HALT:
- printf ("The system is halted.\n");
- break;
- default:
- printf ("Unknown message.\n");
- break;
- }
- }
- if (lqmsg)
- QReplyMsg (qh);
- }
- if (rmask & SIGBREAKF_CTRL_C || !CheckCLISession ())
- {
- if (rmask & SIGBREAKF_CTRL_C)
- printf ("CTRL-C\n");
- else
- printf ("\n%s: End of session.\n", argv[0]);
- QClose (qh);
- break;
- }
- }
- }
- else
- printf ("Can't open shutdown queue.\n");
- }
- else
- printf ("Can't allocate signal.\n");
- CloseTimerDevice ();
- CloseLibrary (QueueBase);
- MyProc -> pr_WindowPtr = WindowPtr;
- exit ( EXIT_SUCCESS );
- }
- ///
-